/**********************************************************************
 * @file uart.c
 **********************************************************************/
#include "./include/uart.h"
#include "./include/cpu.h"
#include "./include/2440addr.h"
#include "./include/hwconfig.h"
#include "./include/sys_dbg.h"
#include "./include/ringbuffer.h"

#include <stdarg.h>
#include <stdio.h>
#include <string.h>

#define UART_CLK PCLK
//默认波特率
#define UART_DEF_BAUD_RATE 115200
//串口设备数量
#define SYS_UART_DEV_COUNT 3
//串口寄存器基地址
#define SYS_UART_DEV_BASE_ADDR 0x50000000

typedef enum UartError_t{
  UART_ERR_NONE = 0,
  UART_ERR_RECV_TIMEOUT,//接收超时
  UART_ERR_SEND_TIMEOUT,//发送超时
  UART_ERR_OVERRUN,//溢出错误
  UART_ERR_PARITY,//校验错误
  UART_ERR_FRAME,//帧错误
  UART_ERR_DEV_ALREADY_OPENED,//设备已经处于打开状态
  UART_ERR_DEV_NOT_EXIST,//串口设备不存在
  UART_ERR_COUNT,
}UartError_t;

typedef enum UartStatus_t{
  UART_STATUS_ERROR = -1,
  UART_STATUS_OK = 0,
  UART_STATUS_BREAK,//断点
  UART_STATUS_RxBUF_RDY,//接收就绪
  UART_STATUS_TxBUF_EMPTY,//发送缓冲为空
  UART_STATUS_TxShifter_EMPTY,//发送移位器为空
  UART_STATUS_COUNT,
}UartStatus_t;

typedef struct UartDevice_t {
  char devName[8]; //设备名称
  UartStatus_t status;//串口设备
  UartError_t errCode;//错误代码

  UINT32 devIndex;//设备索引
  UINT32 baseAddr;//寄存器基地址
  UINT32 uartMode;//串口工作模式

  UINT32 opened : 1;//打开状态
  UINT32 enableRingbuf : 1;
  UINT32 enableFIFO : 1;
  UINT32 flowCtrl : 1;
  UINT32 padding : 28;
  
  RingBuffer_t rxBuf;//接收缓冲区
  RingBuffer_t txBuf;//发送缓冲区

} UartDevice_t;
static UartDevice_t uartDev[SYS_UART_DEV_COUNT];
//////////////////////////////////////////////////////////////
static s3c24x0_uart* Uart__getDevRegObj(DevHandle devHandle) {
  SYS_ASSERT(devHandle!=NULL);
  UartDevice_t *pDev=(UartDevice_t *)devHandle;
  return (s3c24x0_uart *)(pDev->baseAddr);
}

DevHandle Uart_GetDev(const char *pDevName){
  if(!pDevName){
    SYS_ASSERT(FALSE);
    return NULL;
  }

  for(INT32 i=0;i<ARRAY_SIZE(uartDev);i++){
      if(strcasecmp(pDevName,uartDev[i].devName)==0){
          return (DevHandle)(&uartDev[i]);
      }
  }
  
  return NULL;
}

INT32 Uart_GetDevCount(void) { return SYS_UART_DEV_COUNT; }

void Uart_InitModule(void) {
  s3c24x0_uart *pUartReg = NULL;

  for (INT32 i = 0; i < ARRAY_SIZE(uartDev); i++) {

    snprintf(uartDev[i].devName,sizeof(uartDev[i].devName),"Com%d",i+1);
    uartDev[i].devIndex = i;
    uartDev[i].baseAddr = (SYS_UART_DEV_BASE_ADDR + i * 0x4000);
    uartDev[i].uartMode = UART_COMM_TYPE_QUERY;

    uartDev[i].enableFIFO = 0;
    uartDev[i].opened = 0;
    uartDev[i].enableRingbuf = 0;
    uartDev[i].flowCtrl =0;

    pUartReg = (s3c24x0_uart *)(uartDev[i].baseAddr);

    rGPHCON &= ~(0x3 << (4 * i + 4) | 0x3 << (4 * i + 6));
    rGPHCON |= 0x2 << (4 * i + 4) | 0x2 << (4 * i + 6);
    rGPHUP |= (1 << (i + 2) || 1 << (i + 3));

    pUartReg->ulcon = 0x2b; //偶校验，1停止位,8数据位
    pUartReg->ucon = 0x5;
    pUartReg->ufcon = 0;
    pUartReg->umcon = 0;
    pUartReg->ubrdiv = UART_CLK / (UART_DEF_BAUD_RATE * 16) - 1;
  }
}

DevHandle Uart_Open(const char *pDevName,UartConfig_t *pConfig) {
  SYS_ASSERT(pConfig!=NULL);
    
  DevHandle handle = Uart_GetDev(pDevName);
  if(!handle)
    return NULL;

  UartDevice_t *pDev = (UartDevice_t *)handle;

  if (pDev->opened)
    return NULL;
  
  if(!UartConfig_CheckFrameError(pConfig,UART_CLK))
    return NULL;
  
   s3c24x0_uart *pUartReg = Uart__getDevRegObj(pDev);

   pUartReg->ulcon = (pConfig->dataBit | pConfig->stopBit<<2 | pConfig->parity);
   pUartReg->ubrdiv = (INT32)(PCLK/(pConfig->baudRate *16) - 1);
  
  pDev->opened = 1;
  return (DevHandle)pDev;
}

// static void uart_queryStatus(DevHandle devHandle){
//   SYS_ASSERT(devHandle != NULL);
//   UartDevice_t *pDev = (UartDevice_t *)devHandle;

//   s3c24x0_uart *pUartReg = uart_getDevRegObj(pDev->devID-);
// }

BOOL32 Uart_LinkBuffer(DevHandle devHandle, UINT8 *txBuf, UINT32 txBufSize, 
                      UINT8 *rxBuf, UINT32 rxBufSize){

   SYS_ASSERT(devHandle != NULL);
   SYS_ASSERT(txBuf!=NULL);
   SYS_ASSERT(rxBuf!=NULL);
   
   UartDevice_t *pDev = (UartDevice_t *)devHandle;
   
   if(pDev->enableRingbuf)
     return FALSE;

   RingBuffer_Init(&pDev->txBuf,txBuf,txBufSize);
   RingBuffer_Init(&pDev->rxBuf,rxBuf,rxBufSize);
   pDev->enableRingbuf = 1;
   return TRUE;
}

BOOL32 Uart_ConfigFIFO(DevHandle devHandle,UINT32 rxTriggerLevel,UINT32 txTriggerLevel){
  SYS_ASSERT(devHandle != NULL);
  UartDevice_t *pDev = (UartDevice_t *)devHandle;

  if(pDev->enableFIFO)
    return FALSE;

  if(rxTriggerLevel>=RX_FIFO_LEVEL_COUNT)
    return FALSE;
  
   if(txTriggerLevel>=TX_FIFO_LEVEL_COUNT)
    return FALSE;

  s3c24x0_uart *pUartReg = Uart__getDevRegObj(devHandle);

  pUartReg->ufcon &= ~0xF1;
  pUartReg->ufcon |= ((1<<0)|(txTriggerLevel<<6)|(rxTriggerLevel<<4));

  pDev->enableFIFO = 1;
  
  return TRUE;
}

void Uart_Poll(DevHandle devHandle){
  
}

void Uart_PollAll(void){

}

void Uart_ClearError(DevHandle devHandle){
  SYS_ASSERT(devHandle != NULL);
  UartDevice_t *pDev = (UartDevice_t *)devHandle;
  //
}

void Uart_Close(DevHandle devHandle) {
  SYS_ASSERT(devHandle != NULL);
  UartDevice_t *pDev = (UartDevice_t *)devHandle;

  pDev->opened = 0;
  pDev->enableFIFO = 0;
  pDev->enableRingbuf = 0;
  pDev->flowCtrl =0;

  RingBuffer_Reset(&pDev->rxBuf);
  RingBuffer_Reset(&pDev->txBuf);
}

INT32 Uart_Read(DevHandle devHandle, UINT8 *buf,UINT32 bufSize){
  return 0;
}

INT32 Uart_Write(DevHandle devHandle, UINT8 *buf,UINT32 bufSize){
  
}

//将缓冲区的数据立即发送出去
INT32 Uart_Flush(DevHandle devHandle){
  
}
// void uart_setTransferMode(DevHandle devHandle, UINT32 mode) {
//    SYS_ASSERT(devHandle != NULL);
//    SYS_ASSERT(mode < UART_COMM_TYPE_COUNT);

//    UartDevice_t *pDev = (UartDevice_t *)devHandle;
//    if (mode == pDev->uartMode)
//      return;

//    pDev->uartMode = mode;
//    // TODO:设置相关的寄存器
//    // 中断方式该如何处理
//    // 是否该向外提供回调函数
//    // ??????
// }



// UINT8 Uart_Getc(DevHandle devHandle) {
//   SYS_ASSERT(devHandle != NULL);

//   s3c24x0_uart *pUartReg = Uart__getDevRegObj(devHandle);
//   SYS_ASSERT(pUartReg != NULL);

//   while (!(pUartReg->utrstat & 0x1));
//   return pUartReg->urxh;
// }

// void Uart_Putc(DevHandle devHandle, UINT8 c) {
//   SYS_ASSERT(devHandle != NULL);

//   s3c24x0_uart *pUartReg = Uart__getDevRegObj(devHandle);
//   SYS_ASSERT(pUartReg != NULL);

//   while (!(pUartReg->utrstat & 0x4));

//   pUartReg->utxh = c;
// }

// void Uart_RecvData(DevHandle devHandle, char *buf, INT32 toRecvLen) {
//   SYS_ASSERT(toRecvLen > 0);

//   while (toRecvLen > 0) {
//     *buf = uart_getc(devHandle);
//     toRecvLen--;
//     buf++;
//   }
//   *buf = '\0';
// }

// void Uart_SendData(DevHandle devHandle, const char *buf, int sendSize) {
//   while (sendSize > 0) {
//     Uart_Putc(devHandle, *buf);
//     buf++;
//     sendSize--;
//   }
// }

// void Uart_Printf(DevHandle devHandle, char *fmt, ...) {
//   va_list ap;
//   va_start(ap, fmt);
//   Uart_Vprintf(devHandle, fmt, ap);
//   va_end(ap);
// }

// void Uart_Vprintf(DevHandle devHandle, char *fmt, va_list ap) {
//   char buf[512];
//   vsprintf(buf, fmt, ap);
//   Uart_SendData(devHandle, buf, strlen(buf));
// }